using System;
using System.Collections.Generic;
using System.IO;
using System.Media;
using GTA;
using GTA.Native;

namespace CustomPeds;

public static class SoundHelper
{
	public enum PedSoundType
	{
		IsMaleAndNotHero,
		IsHero,
		NotHooker,
		IsHooker
	}

	private static SoundPlayer sp = new SoundPlayer();

	private static DateTime delay = default(DateTime);

	private static PedSoundType soundReplace;

	public static string TempVoiceName = string.Empty;

	private static List<string> hookers = new List<string> { "s_f_y_hooker_01_white_full_01", "s_f_y_hooker_01_white_full_02", "s_f_y_hooker_01_white_full_03", "s_f_y_hooker_02_white_full_01", "s_f_y_hooker_02_white_full_02", "s_f_y_hooker_02_white_full_03", "s_f_y_hooker_03_black_full_01", "s_f_y_hooker_03_black_full_03" };

	public static void PlayExternalSound(string sound, int toTimeMs = 0)
	{
		if (!(DateTime.Now > delay))
		{
			return;
		}
		using MemoryStream stream = new MemoryStream(Convert.FromBase64String(sound));
		sp.Dispose();
		sp.Stream = stream;
		sp.Play();
		if (toTimeMs > 0)
		{
			delay = DateTime.Now.AddMilliseconds(toTimeMs);
		}
	}

	public static void SetVoice(this Ped ped, string voice)
	{
		Function.Call(Hash._0x6C8065A3B780185B, ped, voice);
	}

	public static void PlayAmbientSpeech1(this Ped ped, string speechFile, bool immediately)
	{
		if (immediately)
		{
			Function.Call(Hash._0xB8BEC0CA6F0EDB0F, ped);
		}
		Function.Call(Hash._0xB9EFD5C25018725A, "IsDirectorModeActive", 1);
		Function.Call(Hash._0x8E04FEDD28D42462, ped, speechFile, "SPEECH_PARAMS_FORCE");
		Function.Call(Hash._0xB9EFD5C25018725A, "IsDirectorModeActive", 0);
	}

	public static void PlayAmbientSpeech2(this Ped ped, string speechFile, bool immediately, bool OnReplace = true)
	{
		if (immediately)
		{
			Function.Call(Hash._0xB8BEC0CA6F0EDB0F, ped);
		}
		Function.Call(Hash._0xB9EFD5C25018725A, "IsDirectorModeActive", 1);
		if (OnReplace)
		{
			if (Game.Player.Handle == ped.Handle)
			{
				PlaySoundReplace(speechFile, Main.P1, immediately);
			}
			else
			{
				PlaySoundReplace(speechFile, Main.P2, immediately);
			}
		}
		else
		{
			Function.Call(Hash._0xC6941B4A3A8FBBB9, ped, speechFile, "SPEECH_PARAMS_FORCE");
		}
		Function.Call(Hash._0xB9EFD5C25018725A, "IsDirectorModeActive", 0);
	}

	private static void GetPedSoundType(Origin origin)
	{
		if (origin.Character.Gender == Gender.Male && origin.skin.ModelName != "Franklin" && origin.skin.ModelName != "Michael" && origin.skin.ModelName != "Trevor")
		{
			soundReplace = PedSoundType.IsMaleAndNotHero;
		}
		if ((origin.Character.Gender == Gender.Male && origin.skin.ModelName == "Franklin") || Main.P1.skin.ModelName == "Michael" || origin.skin.ModelName == "Trevor")
		{
			soundReplace = PedSoundType.IsHero;
		}
		if (origin.Character.Gender == Gender.Female && origin.skin.ModelName.ToLower().IndexOf("hooker") == -1)
		{
			soundReplace = PedSoundType.NotHooker;
		}
		if (origin.Character.Gender == Gender.Female && origin.skin.ModelName.ToLower().IndexOf("hooker") >= 0)
		{
			soundReplace = PedSoundType.IsHooker;
		}
	}

	public static void PlaySoundReplace(string sound, Origin origin, bool immediately = false)
	{
		GetPedSoundType(origin);
		_ = soundReplace;
		if (soundReplace == PedSoundType.NotHooker)
		{
			TempVoiceName = hookers[new Random(Guid.NewGuid().GetHashCode()).Next(0, 7)];
			origin.Character.PlayAmbientSpeechWithVoice(sound, TempVoiceName, immediately);
		}
	}

	public static void PlayAmbientSpeechWithVoice(this Ped ped, string speechName, string voiceName, bool immediately)
	{
		if (immediately)
		{
			Function.Call(Hash._0xB8BEC0CA6F0EDB0F, ped);
		}
		Function.Call(Hash._0xB9EFD5C25018725A, "IsDirectorModeActive", 1);
		Function.Call(Hash._0x3523634255FC3318, ped, speechName, voiceName, "SPEECH_PARAMS_FORCE", 0);
		Function.Call(Hash._0xB9EFD5C25018725A, "IsDirectorModeActive", 0);
	}

	public static void IsSpeechPlayingToEnd(this Ped ped)
	{
		DateTime now = DateTime.Now;
		while (Function.Call<bool>(Hash._0x9072C8B49907BFAD, ped))
		{
			Script.Wait(300);
			if (DateTime.Now.Subtract(now).TotalMilliseconds >= 5000.0)
			{
				break;
			}
		}
	}
}
